-- 定义一个块的集合，每个块由多个二维数组表示
方块组={{{0,1,1},{1,1,0}},{{1,1,0},{0,1,1}},{{1,1,1},{0,0,1}},{{1,1,1},{1,0,0}},{{1,1,1},{0,1,0}},{{1,1},{1,1}},{{1,1,1,1}}}

-- 初始化一个空的字段数组，用于游戏地图。
-- 像一个10列（10个格子），22行（22个格子）的空格子。
主体格子={}
主体格子={}
for i=1,22 do
		主体格子[i]={0,0,0,0,0,0,0,0,0,0}
end

-- 随机选择一个块，初始化块的位置，坐标系在左下角，4，19，分别为第列，第19行。
--math.random()是随机数，取值范围1到7。即对应上方的方块组的图案。为什么是19行，如图中所示。刚好是4个竖向方格出现时能全显。
--同样的4列也是这个原因，并且显示居中。
当前方块,方块X坐标,方块Y坐标 = 方块组[math.random(7)],4,19

--检测方块是否与现有的游戏地图重叠
--@当前方块: 要检测的块，
--@方块x坐标: 方块的起始x坐标，
--@方块y坐标: 方块的起始y坐标
--返回值: 如果有重叠返回true（真），否则返回false（假）。
function 检查重叠(当前方块,方块x坐标,方块y坐标)	
	--检查块是否放置在边界之外
	--“当前方块[1]” 是方块的宽度
	--如果 “方块x坐标” 超出边界（横向小于1个格或者大于11格），
	--或者 “方块y坐标” 超出边界，
	--则 返回 “true”（真）
	if 方块x坐标 < 1 or 方块x坐标+#当前方块[1] > 11 or 方块y坐标 < 1 then  
		return true
	end
	
	--检查是否与游戏地图 “主体格子” 现存的方块重叠。 
	--遍历 “当前方块” 的每个元素，检查是否与 “主体格子” 现存的方块重叠
	--主体格子[方块y坐标+i-1] 即在游戏地图上 “主体格子”与对应“当前方块”y坐标的位置，是否现存的方块格子。	
    --当前方块[i][j]即 “当前方块” 的二唯表格位置里的数据，
    --如果大于0，则表示是“主体格子”在当前位置不是空位，即现存的方块与 “当前方块” 相交。
	for i=1,#当前方块 do  			-- 遍历块的每一行，即高度
		 for j=1,#当前方块[1] do 	-- 遍历块的每一列，即宽度
  		 	if 主体格子[方块y坐标+i-1] and 当前方块[i][j] > 0 and 主体格子[方块y坐标+i-1][方块x坐标+j-1] > 0 then
				return true
			end
		end
	end
end
		
-- 下落过程函数
-- 此函数用于处理方块的下落过程，包括方块位置的更新、方块与底部或其它方块的碰撞检测、以及消除满行等逻辑。
function drop()
    方块Y坐标 = 方块Y坐标 - 1  -- 尝试将当前方块下落一行
    
    -- 检测当前方块是否与底部或其它方块发生重叠
    if 检查重叠(当前方块, 方块X坐标, 方块Y坐标) then
        方块Y坐标 = 方块Y坐标 + 1  -- 如果发生重叠，则将 “当前方块” 位置回退到重叠之前
        
        -- 如果没有重叠，将 “当前方块” 的形状数据复制到游戏场地即“主体格子”内
        for i = 1, #当前方块 do 				-- 遍历“当前方块”的每一行
            for j = 1, #当前方块[1] do			-- 遍历“当前方块”的每一列
                if 当前方块[i][j] ~= 0 then		-- 如果“当前方块”的形状数据在这个位置不为空，则将其复制到游戏场地即“主体格子”内
                    主体格子[方块Y坐标 + i - 1][方块X坐标 + j - 1] = 1
                end
            end
        end
        
        -- 检查并消除满行
        for i = 方块Y坐标 + #当前方块 - 1, 方块Y坐标, -1 do
            local 行满吗 = 0  -- 用于统计当前行是否全满的计数器
            for j = 1, 10 do
                行满吗 = 行满吗 + 主体格子[i][j]
            end
            if 行满吗 == 10 then
                table.remove(主体格子, i)  								-- 移除满行
                table.insert(主体格子, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0})  -- 在场地上方补充一行空行
            end
        end
        
        -- 生成新的随机方块，设置其初始位置
        当前方块, 方块X坐标, 方块Y坐标 = 方块组[math.random(7)], 4, 19
    end
end

-- 按键事件处理函数
-- 参数:
--   i: 用户按下的键名（例如"left", "right", "up", "down"等）
function love.keypressed(i)
  -- 处理左键按下事件：方块向左移动，并检查重叠，如果不重叠，即会更新“当前方块”的位置
  if i=="left" then  
    if not 检查重叠(当前方块,方块X坐标-1,方块Y坐标) then
      方块X坐标=方块X坐标-1
    end
  -- 处理右键按下事件：方块向右移动，并检查重叠，如果不重叠，即会更新“当前方块”的位置
  elseif i=="right" then  
    if not 检查重叠(当前方块,方块X坐标+1,方块Y坐标) then
      方块X坐标=方块X坐标+1
    end
  -- 处理上键按下事件：方块旋转，
  elseif i== "up" then  
    local m={}  -- 创建用于存储旋转后方块的新数组
    for i=1,#当前方块[1] do  -- 构建旋转矩阵
      m[i]={}
      for j=1,#当前方块 do
        m[i][j] = 当前方块[j][#当前方块[1]+1-i]
      end
    end
    if not 检查重叠(m,方块X坐标,方块Y坐标) then
      当前方块=m  -- 若无重叠，则使用旋转后的方块数组
    end
  -- 处理下键按下事件：方块加速下落
  elseif i=="down" then
    repeat drop()  -- 不断执行下落操作
      until 方块Y坐标==19  --这里执行效果不高，没做判断，应该有多余的循环次数。但结果是符合的。
  end
end
																																																																																																							-----------------------------------------引擎运行主函数
-- 引擎主循环函数
-- 在Love引擎启动的时候就会调用love.run，这里程序里需要一个非默认的，所以要自己写一个functionlove.run()-引擎工作函数，
-- 重写可以重用。重点哦。
function love.run()	
    -- 初始化计时器
	flag = love.timer.getTime()	
	-- 设置画笔颜色为红色
	love.graphics.setColor(255,0,0)	
	-- 返回一个游戏循环函数
	return function()		
		-- 处理事件队列
		love.event.pump()	
		-- 遍历并处理所有事件，name,a,b,c,d,e,f 是什么呢，要去查一下love.event.poll()的定义去。
		for name,a,b,c,d,e,f in love.event.poll() do
 			-- 如果事件为退出，则终止游戏循环
			if name=="quit" then return 0 end
			-- 调用相应的事件处理函数
			love.handlers[name](a,b,c,d,e,f)
		end
		-- 检查是否需要进行下落操作，.6是什么呢，要去查一下love.timer.getTime()的定义去。
		if love.timer.getTime()-flag >.6 then 
	 		-- 执行下落逻辑 
	 		drop()
	 		-- 重置计时器
	 		flag=love.timer.getTime()
		end
		-- 清空画布
		love.graphics.clear(255,255,255) 	
		-- 绘制场地
		for j=1,20 do
			for i=1,10 do
				if 主体格子[j][i]==1 then
					--这里的40是相素值，-39是偏移量，因为坐标原点在左上角，而方块的左上角在左下角，所以要偏移。
					--这是一个方块的左上角坐标
					love.graphics.rectangle("fill",40*i-39,801-40*j,38,38)
				end
			end
		end	
		-- 绘制下落的方块
		for j=1,#当前方块 do
			for i=1,#当前方块[1]do
				if 当前方块[j][i]==1 then
					love.graphics.rectangle("fill",40*(i+方块X坐标-1)-39,801-40*(j+方块Y坐标-1),38,38)
				end
			end
		end	
		-- 更新屏幕显示
		love.graphics.present() 	
	end
end